#ifndef SNACK_TRACKIMPL_H
#define SNACK_TRACKIMPL_H

#include "Track.h"
#include "CuePoints.h"

#include "api/inc/fmod.hpp"

#include <string>

namespace SnackBreak
{
namespace Impl
{

// Track implementation - uses FMOD to do the work.
// Not for use by UI code etc.
class FMODTrack : public Track
{
public:
	static FMODTrack* Create(std::string f, CuePair q)
	{
		return new FMODTrack(f, q);
	}
	static FMODTrack* Create(std::string f, CuePair q, double lastBeatNum)
	{
		return new FMODTrack(f, q, lastBeatNum);
	}

	// this should really be a member of Track?
	static const double CuePauseFrameLength; // seconds
	static const double CuePauseNudgeProportion;

public:
	FMODTrack(std::string f, CuePair q);
	FMODTrack(CuePair q, double lastBeatNum);
	FMODTrack(std::string f, CuePair q, double lastBeatNum);
	~FMODTrack();

	// Set/get the current play position in beats.
	virtual void setPosition(double beatNumber = 0) const;
	virtual double getPosition() const;

	// Set the relative playback speed. Pass 1.0 for normal speed, 1.1 for +10% etc.
	virtual void setPlayRate(double rateMultiplier) const;

	// Set the volume/fader/level/amplitude. Pass 1.0 for max, 0 for silent.
	virtual void setVolume(double vol) const;

	// Determine if track is playing (true) or paused (false).
	virtual bool IsPlaying() const;

	// Start or resume playback. (continues playing if already playing)
	virtual void Play();

	// Pause playback.
	virtual void Pause();

	// Enter Cue-Pause (CDJ-like frame loop for setting cue) mode.
	virtual void CuePause();

	// Nudge/jog the current cue pause frame forward by numFrames (or backward if negative)
	virtual void NudgeCuePause(int numFrames);

	// Set simple CDJ-style single cue point, based on current play pos or cue-pause pos if in cue-pause mode.
	// (This sets up "beats" to equal seconds in the normal cue scheme.)
	virtual void SetSimpleCue();
    
    // Saves cue info to an xml file alongside the file. This file if present will be read when the file is next opened.
    void AutoSaveCueInfo();

    // Loads cue info from an xml file alongside the file. 
    void AutoLoadCueInfo();
    
	FMOD::Sound* getSound() const { return fmodSound; }; 
	FMOD::Channel* getChannel() const { return fmodChannel; };

private:
	void Init();
	void SetupCuePause(double desiredEndMsec = -1); // pass -1 to specify "use current play pos"
	void UnSetupCuePause() const;

	FMOD::Sound* fmodSound; 
	FMOD::Channel* fmodChannel; 
	double defaultSampleRate;
	struct CueLoop
	{
		double cueLoopStart;
		double cueLoopEnd;
	} cueLoop;
};

}; // namespace Impl
}; // namespace SnackBreak

#endif // SNACK_TRACKIMPL_H